import miniApp, {
    analyticsBase,
    authorizeParams,
    gameRecorderStartParams,
    getUserInfoParams,
    loadParams,
    loginParams, ModalParams, SHARE_VIDEO_SORT_TYPE, ShareVideoRankDetail,
    toastParams, VIBRATE_TYPE
} from "../miniApp";
import gameConfig from "../../../configs/gameConfig";
import {
    getAddShortcutReportData, getBeforeCloseVideoReportData,
    getLoadVideoReportData,
    getLookVideoFailShareReportData,
    getLookVideoReportData,
    getShareGameRecordReportData,
    getShowVideoReportData,
    getVideoFailLoadOrShow
} from "../miniParam";
import data_control from "../../../libs/data_control";
import { dataField } from "../dataField";
import O1HD, { modules } from "../../../gameEngine";

export interface TtRewardedVideoAdParam {
    // 名称	数据类型	属性	默认值	描述
    adUnitId: string;		//required	广告位 id
}

export interface TtVideoAd {
    // 通过 load 方法主动预加载广告内容。
    // 此外，在显示广告出现问题时也可以尝试主动 load 一次。
    // 该方法返回一个 Promise，如果广告已经自动拉取成功，调用该方法返回一个 resolved Promise；
    load: () => Promise<any>;
    // 广告创建后默认是隐藏的，可以通过该方法显示广告。 该方法返回一个 Promise 对象。当广告组件正常获取素材时，该 Promise 对象会是一个 resolved Promise。当广告组件发生错误时，会是一个 rejected Promise，参数与error事件监听器获得的参数相同。
    show: () => Promise<any>;
    //绑定 load 事件的监听器，用户在手动调用 load 方法后，广告组件会预先加载。 广告组件成功拉取广告素材时会触发load事件的监听器。
    //确保监听此事件时，开发者主动调用过 load 方法。
    onLoad: (listener: Function) => void;
    // 解除绑定 load 事件的监听器。
    offLoad: (listener: Function) => void;
    //绑定 error 事件的监听器。 广告组件拉取广告素材和其他情况下如果发生错误，会触发error事件的监听器。监听器会获得一个包含errCode和errMsg属性的对象参数。
    //     errCode 详情
    onError: (listener: (error: any) => void) => void;
    //    解除绑定 error 事件的监听器。
    offError: (listener: Function) => void;
    //    绑定 close 事件的监听器。 当用户点击了 Video 广告上的关闭按钮时，会触发close事件的监听器。监听器会获得一个包含isEnded属性的对象参数，表征用户是否完整观看了视频。
    onClose: (listener: (res: { isEnded: boolean }) => void) => void;
    //解除绑定 close 事件的监听器。
    offClose: (listener: Function) => void;
    //
    destroy: () => Promise<any>;
}

//开始录音参数
export interface RecorderMgrStartParam {
    duration?: number;//	60000	否	录音自动完成时长，单位 ms	1.0.0
    sampleRate?: number;//	8000	否	采样率	1.0.0
    numberOfChannels?: number;//	1	否	录音通道数	1.0.0
    encodeBitRate?: number;//	48000	否	码率	1.0.0
    frameSize?: number;//	8000	否	帧大小，单位 KB。如果设置了值，那么每当录音内容达到帧大小时会通过 RecorderManager.onFrameRecorded 返回内容
}

export interface RecorderManager {
    start: (option?: RecorderMgrStartParam) => void;//	开始录音
    pause: () => void;//	暂停录音
    resume: () => void;//	继续录音
    stop: () => void;//	停止录音
    onStart: (callback: () => void) => void;//	监听录音开始事件
    onPause: (callback: () => void) => void;//	监听录音暂停事件
    onResume: (callback: () => void) => void;//	监听录音继续事件
    onStop: (callback: (res: { tempFilePath: string }) => void) => void;//	监听录音结束事件
    onError: (callback: (e: { errMsg: string }) => void) => void;//	监听录音错误事件
    onFrameRecorded: (callback: (res: { frameBuffer: ArrayBuffer, isLastFrame: boolean }) => void) => void;//	监听已录制完指定帧大小的文件事件。如果设置了 frameSize，则会回调此事件，不设置则不会回调
}

const tt: any = window['tt'];
export default class TtApi extends miniApp {
    drawHead(headUrl: string): Promise<cc.SpriteFrame> {
return;
    }
    fullScreenVideo(): Promise<void> {
return;
    }
    WidgetfullScreen(): Promise<void> {
return;
    }
    //神奇的方块字
    // protected m_appId: string = 'tt52de2463cde692fe02';//小小运动员
    protected m_appId: string = 'tt9870eecd0743573702';
    protected m_secret: string = '02049ac4a77c4344b568f2ddc850443e4ed7e32b';

    protected m_adUnitId: string = '1854f267603j8nv7jk';
    protected m_adUnitIdList: string[] = ['1854f267603j8nv7jk', '1854f267603j8nv7jk', '1854f267603j8nv7jk'];
    protected m_BannerId: string = "1n8t3fst2tro0e3okn"
    protected m_InsertId: string = "7leon10m65h10ifea0"

    // 老乡你要啥
    // protected m_appId: string = 'tt3a5c4ce1a56771f4';
    // protected m_secret: string = '480928071e1cc3f2cdbda01ea2d174441e2f880c';
    // //
    // protected m_adUnitId: string = '11flm74jfpgml93lhhb';
    // protected m_adUnitIdList: string[] = ['11flm74jfpgml93lhhb'];
    // protected m_BannerId: string = "13h3c9a8a346m3i82ca"
    // protected m_InsertId: string = "1mm9mdb790h929g3waj"

    // 愤怒的黄瓜
    // protected m_appId: string = 'tt1fed695080d61c40';
    // protected m_secret: string = '5aac06c0d4536ed8ad966881d38704e93c465d5a';
    // //
    // protected m_adUnitId: string = '3chdculk0porbe6q7e';
    // protected m_adUnitIdList: string[] = ['3chdculk0porbe6q7e'];
    // protected m_BannerId: string = "tohunsff53qi4uuf8p"
    // protected m_InsertId: string = "1j8jdimg9hbka58cji"

    //
    private m_accessToken: string = null;
    //录屏管理器
    private m_gameRecorderManager: any = null;
    //录屏文件保存完地址
    private m_gameRecordVideoUrl: string = null;
    //视频广告组件
    private m_videoAd: TtVideoAd = null;
    //录音管理器
    private m_soundRecordManager: RecorderManager = null;
    //音频文件
    private m_lastRecordSoundPath: string = null;

    //


    getUserInfo(params: getUserInfoParams): void {
        tt.getUserInfo(params);
    }

    showToast(params: toastParams): void {
        tt.showToast(params);
    }

    showLoading(params: loadParams): void {
        tt.showLoading(params);
    }

    showModal(params: ModalParams): void {
        tt.showModal(params);
    }

    hideLoading(): void {
        tt.hideLoading()
    }
    getSystemInfoSync(){
        return tt.getSystemInfoSync()
    }

    preCreateUnits(): void {
        this.m_gameRecorderManager = tt.getGameRecorderManager();
        this.CheckLocalToBlockCityList();
        //
        tt.onMemoryWarning(() => {
            // this.showToast({title: '内存不足'});
            tt.triggerGC();
        });
    }

    private onShareAppMessageGetReward(successCallback: () => void, errorCallback: (error: any) => void, completeCallback: () => void, isNeedModal?: boolean) {
        //
        let shareAppRewardFunction = () => {
            tt.shareAppMessage({
                templateId: "2w1ji856pahdij2f29", // 替换成通过审核的分享ID
                query: "",
                success: () => {
                    console.log("tt 分享成功");
                    let shareResult = getLookVideoFailShareReportData('分享成功');
                    this.reportAnalytics(shareResult.key, shareResult.obj);
                    successCallback();
                    completeCallback && completeCallback();
                },
                fail: (e) => {
                    console.log("tt 分享失败");
                    let shareResult = getLookVideoFailShareReportData('分享失败');
                    this.reportAnalytics(shareResult.key, shareResult.obj);
                    errorCallback(e);
                    completeCallback && completeCallback();
                },

            })
        }
        //
        if (isNeedModal) {
            console.log("tt 拉起分享");
            let shareResult = getLookVideoFailShareReportData('拉起分享');
            this.reportAnalytics(shareResult.key, shareResult.obj);
            this.showModal({
                title: '游戏奖励',
                content: '视频拉取失败,分享游戏也可领取视频奖励',
                confirmText: '分享',
                showCancel: true,
                success: (info) => {
                    console.log('tt 分享success');
                    if (info.confirm) {
                        shareAppRewardFunction();
                    } else {
                        errorCallback(null);
                        completeCallback();
                    }
                },
            })
        } else {
            shareAppRewardFunction();
        }
    }

    createMoreGameBtn()//创建更多游戏按钮
    {
        //  按钮类型为image
        const buttonWithImage = tt.createMoreGamesButton({
            type: "text",
            style: {
                left: 120,
                top: 400,
                width: 120,
                height: 100,
                backgroundColor: "#ffffff",
                borderColor: "#ffff00",
                borderWidth: 10,
                borderRadius: 10,
                textAlign: "left",
                fontSize: 13,
                lineHeight: 50,
                textColor: "#000000",
            },
            text: "text的button",
            actionType: "box",
            appLaunchOptions: [
                {
                    appId: this.m_appId,
                    query: tt.getLaunchOptionsSync().query,
                    extraData: {},
                },
                // {...}
            ],
            onNavigateToMiniGameBox(res) {
                console.log("跳转到小游戏盒子", res);
            },
        });

        let handler = () => {
            console.log("点击更多游戏按钮");
        };
        // 取消监听点击更多游戏按钮事件
        buttonWithImage.offTap(handler);
        // 监听点击更多游戏按钮事件
        buttonWithImage.onTap(handler);
        // 显示更多游戏按钮
        buttonWithImage.show();
        // // 隐藏更多游戏按钮
        //         buttonWithImage.hide();
        // // 销毁更多游戏按钮
        //         buttonWithImage.destroy();
        // const buttonWithText = tt.createMoreGamesButton({
        //     type: "text",
        //     style: {
        //         left: 120,
        //         top: 400,
        //         width: 120,
        //         height: 100,
        //         backgroundColor: "#ffffff",
        //         borderColor: "#ffff00",
        //         borderWidth: 10,
        //         borderRadius: 10,
        //         textAlign: "left",
        //         fontSize: 13,
        //         lineHeight: 50,
        //         textColor: "#000000",
        //     },
        //     text: "text的button",
        //     actionType: "box",
        //     appLaunchOptions: [
        //         {
        //             appId: this.m_appId,
        //             query: tt.getLaunchOptionsSync().query,
        //             extraData: {},
        //         },
        //         // {...}
        //     ],
        //     onNavigateToMiniGameBox(res) {
        //         console.log("跳转到小游戏盒子", res);
        //     },
        // });
    }

    showInterstitialAd(onAdClose: () => void, onFailed: () => void) {//展示插屏广告！！！！
        if (tt) {

            console.log("加抖音 插屏 广告");
            let interstitialAd = tt.createInterstitialAd({
                adUnitId: this.m_InsertId,
            })
            interstitialAd.load()
            interstitialAd.onLoad(() => {
                console.warn('插屏广告 加载完成');

                interstitialAd.show().catch((err) => {
                    console.warn('插屏广告 显示失败 ：' + JSON.stringify(err))
                    interstitialAd.destroy();
                    interstitialAd = null;
                    if (onFailed) {
                        onFailed();
                    }
                })

            })

            interstitialAd.onError((err) => {
                console.warn('插屏广告 加载失败' + JSON.stringify(err));
                interstitialAd.destroy();
                interstitialAd = null;
                if (onFailed) {
                    onFailed();
                }
            })

            interstitialAd.onClose(() => {
                console.warn('插屏广告 关闭');
                if (interstitialAd != null) {
                    interstitialAd.destroy();
                    interstitialAd = null;
                }
                if (onAdClose) {
                    onAdClose();
                }
            })
        } else {
            onAdClose();
        }
    }

    protected m_BannerAd: any = null
    private bannerSuccess: boolean = true;

    showBannerAD(node: cc.Node)//展示banner广告
    {
        const { windowWidth, windowHeight } = tt.getSystemInfoSync();
        let targetBannerAdWidth = 200;
        if (this.m_BannerAd && this.bannerSuccess == false) {
            this.m_BannerAd.destroy()
            this.m_BannerAd = null
        }
        if (this.m_BannerAd) {
            this.m_BannerAd.show()
                .then(() => {
                    console.log("广告显示成功");
                })
                .catch((err) => {
                    console.log("广告组件出现问题", err);
                });
            return
        }
        this.bannerSuccess = true
        this.m_BannerAd = tt.createBannerAd({
            adUnitId: this.m_BannerId,
            adIntervals: 30,
            style: {
                width: targetBannerAdWidth,
                top: windowHeight - (targetBannerAdWidth / 16) * 9, // 根据系统约定尺寸计算出广告高度
            }
        });//创建
        this.m_BannerAd.onResize(size => {
            console.log(size.width, size.height, "banner长宽");
            this.m_BannerAd.style.top = windowHeight - size.height;
            this.m_BannerAd.style.left = (windowWidth - size.width) / 2;
        });
        this.m_BannerAd.onLoad(() => {
            if (node == null || !node.active || !node.isValid) {
                return
            }
            this.m_BannerAd
                .show()
                .then(() => {
                    console.log("广告显示成功");
                })
                .catch((err) => {
                    console.log("广告组件出现问题", err);
                });
        });
        this.m_BannerAd.onError((e) => {
            this.bannerSuccess = false
            console.log("广告显示错误,错误原因：", e)
        })
    }

    hideBanner()//隐鲹banner广告
    {
        if (null != this.m_BannerAd) {
            this.m_BannerAd.hide();
        }
    }

    showNativeAd() {

    }

    //错误回调监听
    private OnVideoAdErrorCallback: (e: { errCode: number, errMsg: string }) => void = null;

    //错误方法
    private OnVideoAdError(e: { errCode: number, errMsg: string }) {
        console.error('tt 视频广告错误', e);
        //
        let reportData = getVideoFailLoadOrShow([`${e.errCode}`, e.errMsg]);
        this.reportAnalytics(reportData.key, reportData.obj);
    }

    private wasVideo:boolean=false
    loadAndShowVideoAd(successCallback: () => void,
        errorCallback: (error: any) => void,
        completeCallback?: () => void,
        reportAnalyticsExplain: string = '未定义说明',
        videoIdPos: number = 0): void {// 显示广告
        //

        if(this.wasVideo)
        {
            return
        }
        this.wasVideo=true;
        cc.director.pause();
        // successCallback && successCallback();
        // completeCallback && completeCallback();
        // return;
        if (gameConfig.VIDIOCONTR == 0) {
            cc.director.resume();
            // setTimeout(successCallback,0.1);
            // successCallback && successCallback();
            completeCallback && completeCallback();
            this.wasVideo=false;
            return
        }

        this.showLoading({ title: '请求中', mask: true });
        //错误上报
        if (this.OnVideoAdErrorCallback == null) {
            this.OnVideoAdErrorCallback = this.OnVideoAdError.bind(this);
        }
        //
        const adUnitId = data_control.getRandItemOfArray(this.m_adUnitIdList);
        console.log('tt 视频广告', adUnitId, reportAnalyticsExplain);

        //创建 视频
        const videoAd: TtVideoAd = tt.createRewardedVideoAd({
            adUnitId: adUnitId,
        });

        //监听 视频错误 防止重复监听
        videoAd.offError(this.OnVideoAdErrorCallback);
        videoAd.onError(this.OnVideoAdErrorCallback);

        //监听 视频关闭
        let onCloseVideoAd = (res) => {
            //
            videoAd.offClose(onCloseVideoAd);
            cc.director.resume();
            console.log('tt 视频广告关闭', res);
            if (res && res.isEnded) {
                //上报奖励
                let reportData = getLookVideoReportData(reportAnalyticsExplain);
                this.reportAnalytics(reportData.key, reportData.obj);
                // 给予奖励
                successCallback();
            } else {
                //上报提前关闭
                let reportLoad = getBeforeCloseVideoReportData(reportAnalyticsExplain);
                this.reportAnalytics(reportLoad.key, reportLoad.obj);
                //
                errorCallback('视频中途退出');
            }
            completeCallback && completeCallback();
            this.wasVideo=false
        };

        //展示失败可以重试
        let onTryAgain = (e: any) => {
            //上报拉取
            let reportLoad = getLoadVideoReportData(reportAnalyticsExplain);
            this.reportAnalytics(reportLoad.key, reportLoad.obj);
            //
            videoAd.load().then(() => {
                //上报展示
                let reportLoad = getShowVideoReportData(reportAnalyticsExplain);
                this.reportAnalytics(reportLoad.key, reportLoad.obj);
                videoAd.show().then(() => {
                    this.hideLoading();
                    videoAd.onClose(onCloseVideoAd);
                    //展示异常
                }).catch((e) => {
                    errorCallback && errorCallback('视频展示异常');
                    cc.director.resume();
                    completeCallback && completeCallback();
                    this.wasVideo=true;
                })
                //加载异常
            }).catch((e) => {
                errorCallback && errorCallback('视频拉取异常02');
                cc.director.resume();
                completeCallback && completeCallback();
                this.wasVideo=true;
            });
        }

        //加载 Promise
        //上报拉取
        // let reportLoad = getLoadVideoReportData(reportAnalyticsExplain);
        // this.reportAnalytics(reportLoad.key, reportLoad.obj);
        //
        // videoAd.load().then(() => {
        //上报展示
        let reportLoad = getShowVideoReportData(reportAnalyticsExplain);
        this.reportAnalytics(reportLoad.key, reportLoad.obj);
        console.log('展示一次');
        videoAd.show().then(() => {
            this.hideLoading();
            videoAd.onClose(onCloseVideoAd);
            //展示异常
        }).catch((e) => {
            console.log('重试一次');
            onTryAgain(e);
        })
        //加载异常
        // }).catch((e) => {
        //     errorCallback && errorCallback('视频拉取异常01');
        //     completeCallback && completeCallback();
        // });
    }

    login(params: loginParams): void {
        tt.login(params);
    }

    authorize(params: authorizeParams): void {
        params.success && params.success();
    }

    private m_gameRecordTimeNow: number = 0;

    //
    operateGameLive(): void {
        console.log('tt operateGameLive');
        tt.operateGameLive({
            type: "start",
            success(res) {
                console.log("tt operateGameLive success", res);
            },
            fail(res) {
                console.log("tt operateGameLive fail", res);
                // ...
            }
        })

        tt.onGameLiveStatusChange((res) => {
            console.log('tt 直播状态变化', res);
        });
    }

    gameRecordStart(params: gameRecorderStartParams, onStart?: (res) => void): void {
        if (!this.isHaveShareVideo()) return;
        this.m_gameRecordTimeNow = Date.now();
        this.m_gameRecordVideoUrl = null;
        this.m_gameRecorderManager.onStart((res) => {
            console.log('tt 录屏开始', res);
            onStart && onStart(res);
        });
        this.m_gameRecorderManager.onStop((res: any) => {
            console.log('tt 录屏结束', res.videoPath);
            this.m_gameRecordVideoUrl = res.videoPath;
        });
        this.m_gameRecorderManager.start(params);
    }

    gameRecordStop(): boolean {
        if (!this.isHaveShareVideo()) return false;
        if (Date.now() - this.m_gameRecordTimeNow < 3500) {
            return false;
        }
        this.m_gameRecorderManager.stop();
        return true;
    }

    isGameRecordOver(): boolean {
        return this.m_gameRecordVideoUrl != null;
    }

    shareGameRecordVideo(successCb?: () => void, failCb?: (e?) => void): void {
        if (!this.isHaveShareVideo()) return;
        if (this.m_gameRecordVideoUrl) {
            tt.shareAppMessage({
                channel: "video",
                title: gameConfig.GAME_NAME,
                desc: gameConfig.GAME_VIDEO_SHARE_DESC,
                extra: {
                    hashtag_list: [gameConfig.GAME_NAME],
                    videoPath: this.m_gameRecordVideoUrl, // 可替换成录屏得到的视频地址
                    videoTopics: [gameConfig.GAME_NAME],
                    video_title: gameConfig.GAME_VIDEO_SHARE_TITLE,
                    withVideoId: true,
                    defaultBgm: 'https://v.douyin.com/JmcxWo8/',
                },
                success: (res) => {
                    let shareGameRecord = getShareGameRecordReportData('分享成功');
                    this.reportAnalytics(shareGameRecord.key, shareGameRecord.obj);
                    console.log("tt 分享视频成功");
                    //
                    console.log(res.videoId);
                    console.log(res.shareWithShareBgmStatus); //回调参数
                    console.log("分享视频成功 4");
                    successCb && successCb();
                },
                fail: (e) => {
                    let shareGameRecord = getShareGameRecordReportData('分享失败');
                    this.reportAnalytics(shareGameRecord.key, shareGameRecord.obj);
                    console.log("tt 分享视频失败", e);
                    // modules().uiControlModule.showMessageBox("分享视频时长不能少于3秒");
                    if (e.errMsg == 'shareAppMessage:cancel') {
                        modules().uiControlModule.showMessageBox("取消分享");
                    }
                    failCb && failCb(e)
                }
            });
        } else {
            failCb && failCb(null);
            modules().uiControlModule.showMessageBox("分享视频时长不能少于3秒");
            console.log("tt 分享视频为空");
        }
    }

    //添加桌面
    addShortcut(): Promise<boolean> {
        return new Promise((resolve, reject) => {
            tt.addShortcut({
                success: () => {
                    let ret = getAddShortcutReportData('添加成功');
                    this.reportAnalytics(ret.key, ret.obj);
                    resolve(true);
                },
                fail: () => {
                    let ret = getAddShortcutReportData('添加失败');
                    this.reportAnalytics(ret.key, ret.obj);
                    resolve(false);
                }
            })
        });
    }

    /**production    线上版
     development    测试版
     preview    预览版
     * */
    isProduction(): boolean {
        return TtApi.isProduction();
    }

    isHaveShareVideo(): boolean {
        return true;
    }

    //判断是否合法APP-ID
    validAppId(): void {
        // tt.onShow((res: { query, refererInfo: { appId: string, extraData: {} } }) => {
        //     console.log(res.refererInfo.appId,this.m_appId,"appid对比")
        //     if (res.refererInfo.appId != this.m_appId) {
        //         cc.game.end();
        //         throw '非法盗用此程序将受到法律制裁';
        //     } else {
        //         console.log('tt APP-ID 授权成功');
        //     }
        // });
    }

    reportAnalytics(eventKey: string, data: any): void {
        console.log("tt 发送埋点", eventKey, data);
        tt.reportAnalytics(eventKey, data);
    }

    clearMemory(): void {

    }

    shareAppMessage(args: any): void {
    }

    protected createRewardedVideoAd(param: TtRewardedVideoAdParam) {
        this.m_videoAd = tt.createRewardedVideoAd(param);
    }

    private async getAccessToken() {
        return new Promise((resolve) => {
            //没有就请求
            if (this.m_accessToken) {
                resolve(this.m_accessToken);
                return;
            }
            //
            const url = `https://developer.toutiao.com/api/apps/token?appid=${this.m_appId}&secret=${this.m_secret}&grant_type=client_credential`
            tt.request({
                url: url,
                success: (res: { statusCode: number, errMsg: string, header: object, data: { access_token: string, expires_in: number } }) => {
                    if (res.statusCode != 200) {
                        console.error('#652错误 获取Access_token状态错误', res.errMsg, res);
                        resolve(null);
                        return;
                    }
                    this.m_accessToken = res.data.access_token;
                    resolve(this.m_accessToken);
                },
                fail: (err: { errMsg: string }) => {
                    console.error('#654错误 获取access_token失败', err);
                    resolve(null);
                }
            })
        })
    }

    /**production    线上版
     development    测试版
     preview    预览版
     * */
    static isProduction() {
        return tt.env.VERSION == 'production';
    }

    reportAdClickNativeAd(): void {
    }

    getShareVideoRank(sortType: SHARE_VIDEO_SORT_TYPE, successCb: (data: ShareVideoRankDetail[]) => void): void {
        this.getAccessToken().then((accessToken: string) => {
            console.log('当前token', accessToken);
            let url: string = '';
            switch (sortType) {
                case SHARE_VIDEO_SORT_TYPE.HOT: {
                    url = 'https://gate.snssdk.com/developer/api/get_top_video_ids_by_like';
                    break;
                }
                case SHARE_VIDEO_SORT_TYPE.TIME: {
                    url = 'https://gate.snssdk.com/developer/api/get_top_video_ids_by_time';
                    break;
                }
                default: {
                    console.error('#661 错误获取排行排序类型错误');
                    return;
                }
            }
            //
            tt.request({
                url: url,
                method: "POST",
                data: {
                    app_id: this.m_appId,
                    number_of_top: 20,
                    // tag: "testTag1", //分享视频时传入videoTag情况下，用于筛选指定tag视频
                    access_token: accessToken,
                    // rank_type: "month", //只有  get_top_video_ids_by_like 接口支持
                },
                success: (res: {
                    statusCode: number,
                    errMsg: string,
                    header: object,
                    data: { err_no: number, message: string, data: ShareVideoRankDetail[] }
                }) => {//状态码：0 表示正常返回，其他为失败
                    console.log("排行榜信息", res.data);
                    if (res.statusCode != 200) {
                        console.error('#725 错误的排行榜', res.statusCode, res.errMsg, res);
                        return;
                    }
                    if (res.data) {
                        successCb(res.data.data);
                    }
                    successCb([]);
                    // 从res中获取所需视频信息（videoId数组索引与返回数据数组索引一一对应）
                },
                fail: (err: { errMsg: string }) => {
                    console.error('#736错误 ', err);
                    tt.showToast({ title: '请求超时' });
                    successCb([]);
                }
            });
        }).catch((e) => {
            console.error('#706 异常', e);
            successCb([]);
        });
    }

    drawUrlImage(url: string, overCb: (spf: cc.SpriteFrame) => void): void {
        const image = tt.createImage();
        image.src = url;
        console.log("tt 加载图片", url);
        image.addEventListener("load", (res) => {
            console.log("tt 加载成功 RGBA8888", res);
            if (res && res.target && res.target.data) {
                let texture = new cc.Texture2D();
                texture.initWithElement(image/*res.target.data, cc.Texture2D.PixelFormat.RGBA8888, res.target.width, res.target.height*/);
                texture.handleLoadedTexture();
                let spf = new cc.SpriteFrame(texture);
                overCb(spf);
            }
        });
        image.addEventListener("error", (res) => {
            console.error("tt 图片加载失败", res);
        });
    }

    showVideo(videoUrl: string): void {
        console.log('tt 播放视频', videoUrl);
        //播放视频
        tt.navigateToVideoView({
            videoId: videoUrl,
            success: (res) => {
                /* res结构： {errMsg: string } */
                console.log("tt done", res);
            },
            fail: (err: { errCode: number, errMsg: string }) => {
                switch (err.errCode) {
                    case 1002: {
                        tt.showToast({ title: '视频被删除' });
                        break;
                    }
                }
                console.error('#772 播放错误', err);
            },
        });
    }

    subscribeMessage(successCallback?: () => void, failCallback?: () => void, completeCallback?: () => void): void {
        tt.requestSubscribeMessage({
            tmplIds: ['MSG11613335c650b014f0bcdffad5afb4c8cb0354113715'], // 需要填入开放平台申请的模版id，支持最多3个同类型模版
            success: (res) => {
                //订阅成功
                console.log("订阅成功", res);
                this.showToast({ title: '订阅成功' });
                successCallback && successCallback();
            },
            fail: (error) => {
                //订阅失败
                console.log("订阅失败, 错误详情:", error);
                this.showToast({
                    title: "订阅失败",
                    icon: "fail",
                });
                failCallback && failCallback();
            },
            complete: (res) => {
                //订阅完成
                console.log("tt.requestSubscribeMessage API调用完成: ", res);
                completeCallback && completeCallback();
            },
        });
    }

    showAddFavoriteGuide(successCallback?: () => void, failCallback?: () => void, completeCallback?: () => void): void {
        tt.showFavoriteGuide({
            content: "一键添加到我的小程序",
            success: (res) => {
                console.log("引导组件展示成功");
                successCallback && successCallback();
            },
            fail: (res) => {
                console.warn("引导组件展示失败", res);
                failCallback && failCallback();
            },
            complete: (res) => {
                completeCallback && completeCallback();
            }
        });
    }

    StartRecordSound(): void {
        if (this.m_soundRecordManager == null) {
            this.m_soundRecordManager = tt.getRecorderManager();
        }
        this.m_soundRecordManager.onError(e => {
            console.error('tt 录音错误', e.errMsg, e);
        })
        this.m_soundRecordManager.onStart(() => {
            console.log('tt 录音已开始');
        })
        //
        console.log('tt 开始录音');
        this.m_soundRecordManager.start({
            duration: 60000,
            sampleRate: 44100,//8000,
            numberOfChannels: 2,
            encodeBitRate: 128000,
            frameSize: 8000,
        });
    }

    StopRecordSound(successCallback?: () => void): void {
        console.log('tt 结束录音');
        //
        this.m_soundRecordManager.onStop((res) => {
            console.log('tt 录音已结束', res.tempFilePath);
            this.m_lastRecordSoundPath = res.tempFilePath;

            successCallback && successCallback();
        });
        //
        this.m_soundRecordManager.stop();
    }

    private getChangeAudioBuffer(srcBuffer: AudioBuffer, scale: number): AudioBuffer {
        const ctx = tt.getAudioContext();
        const buf = ctx.createBuffer(srcBuffer.numberOfChannels, srcBuffer.length * scale, srcBuffer.sampleRate);

        console.log('tt 变声可以在这执行 源长', srcBuffer.length, scale);
        for (let channel = 0; channel < buf.numberOfChannels; channel++) {
            const arr = buf.getChannelData(channel);
            const srcArr = srcBuffer.getChannelData(channel);
            console.log('tt 变声可以在这执行 目标长', buf.length);
            for (let i = 0; i < buf.length; i++) {
                arr[i] = srcArr[Math.floor(i / scale)];
            }
        }

        return buf;
    }

    PlayLastRecordSound(scale?: number, successCb?: () => void, errorCb?: () => void) {
        if (!this.m_lastRecordSoundPath) {
            console.error('#918错误 未有的数据');
            errorCb && errorCb();
        }
        //
        scale = scale || 1;
        console.log('tt 播放变音 2', scale);
        //
        let fileSystemManager = tt.getFileSystemManager();
        fileSystemManager.readFile({
            filePath: this.m_lastRecordSoundPath,
            success: (res: { data: ArrayBuffer }) => {
                console.log('tt 文件读取成功', res);
                // 播放
                const ctx = tt.getAudioContext();
                console.log('tt 开始解析', res.data);
                ctx.decodeAudioData(res.data).then((audioBuffer: AudioBuffer) => {

                    const buf = this.getChangeAudioBuffer(audioBuffer, scale);
                    console.log('tt 播放', buf);
                    const source = ctx.createBufferSource();
                    source.buffer = buf;
                    // source.playbackRate.value = 1 / scale;
                    source.connect(ctx.destination);
                    source.start();
                    source.onended = function () {
                        console.log("tt 播放结束", this);
                        successCb && successCb();
                    };
                }).catch((err: DOMException) => {
                    console.error("解码出错", err.name, err.message, err.code);
                    console.error("解码出错 JSON", JSON.stringify(err));
                    errorCb && errorCb();
                });
            },
            fail: (e) => {
                errorCb && errorCb();
                console.error('#927 文件读取错误', JSON.stringify(e));
            }
        });
    }

    playerOnlineSound(tempo: number, pitch: number) {
        console.log('播放在线音频 14');
        //  创建一个 AudioContext
        const ctx = tt.getAudioContext();
        let request = new XMLHttpRequest();
        request.open("GET", 'http://hao.haolingsheng.com/ring/000/991/86ced5cdc9783286406185bc0738502e.mp3', true);
        /*"http://hao.haolingsheng.com/ring/000/992/833a6bfabfbde371ab75ed77c1960b53.mp3"*/
        /*http://hao.haolingsheng.com/ring/000/993/7bff75924dab3ade43248b3f4a132125.mp3*/
        request.responseType = "arraybuffer";

        //
        request.onload = function () {
            let audioData = request.response;
            console.log('收到了');
            console.log('解析在线数据', audioData);
            ctx
                .decodeAudioData(audioData)
                .then((audioBuffer: AudioBuffer) => {
                    console.log(audioBuffer);
                    const source = ctx.createBufferSource();
                    //
                    source.buffer = audioBuffer;
                    source.connect(ctx.destination);
                    if (tempo == 0.5) {
                        //start
                        //end
                    }
                    source.start();
                    source.onended = function () {
                        console.log("onended called", this);
                    };
                })
                .catch((err) => {
                    console.error("解码出错", err);
                });
        };

        request.send();
    }

    private m_localInBlockCity: boolean = false;

    private CheckLocalToBlockCityList(): void {
        this.m_localInBlockCity = false;
    }

    LocalInBlockCityList(): boolean {
        return this.m_localInBlockCity;
    }

    vibrate(type: VIBRATE_TYPE): void {
        switch (type) {
            case VIBRATE_TYPE.LONG: {
                tt.vibrateLong();
                break;
            }
            case VIBRATE_TYPE.SHORT: {
                tt.vibrateShort();
                break;
            }
        }
    }


    async commitRank(score: number): Promise<boolean> {
        // console.debug('tt 提交分数 1');
        // if (!await this.isAntherUserInfo()) {
        //     console.debug('tt 尚未授权');
        //     if (!await this.goLoginSelect('提交排行榜分数')) {
        //         console.debug('tt 授权失败');
        //         this.showToast({title: '用户授权失败'});
        //         return Promise.resolve(false);
        //     }
        //     console.debug('tt 授权成功');
        // }
        // //设置分组
        // tt.setUserGroup({
        //     groupId: dataField.RANK_GROUP.TT_USER
        // });
        // //提交排行榜
        // const option = <dataField.RankInterface>{};
        // option.score = score;
        // option.rankId = rankId;
        // option.operaType = dataField.OPERA_TYPE.COMMIT_SCORE;
        // tt.getOpenDataContext().postMessage(option);
        // return Promise.resolve(true);
        return new Promise<boolean>(resolve=>{
            if(tt.setImRankData){
                tt.setImRankData({
                    dataType: 0, //成绩为数字类型
                    value: score.toString(), //该用户得了999999分
                    priority: 0, //dataType为数字类型，不需要权重，直接传0
                    extra: "extra",
                    success(res) {
                      console.log(`setImRankData success res: ${res}`);
                        resolve(true);
                    },
                    fail(res) {
                      console.log(`setImRankData fail res: ${res.errMsg}`);
                      resolve(false);
                    },
                });
            }else{
                console.log("设置排行榜分数错误,头条版本号过低");
                resolve(false);
            }
        });
    }

    async showRank(): Promise<boolean> {
        // if (!await this.isAntherUserInfo()) {
        //     if (!await this.goLoginSelect('查看排行榜分数')) {
        //         this.showToast({title: '用户授权失败'});
        //         return Promise.resolve(false);
        //     }
        // }
        // const option = <dataField.RankInterface>{};
        // option.rankId = rankId;
        // option.operaType = dataField.OPERA_TYPE.SHOW_SCORE;
        // tt.getOpenDataContext().postMessage(option);
        // return Promise.resolve(true);
        if (!await this.isAntherUserInfo()) {
            console.debug('tt 尚未授权');
            if (!await this.goLoginSelect('提交排行榜分数')) {
                console.debug('tt 授权失败');
                this.showToast({title: '用户授权失败'});
                return Promise.resolve(false);
            }
            console.debug('tt 授权成功');
        }
        return new Promise<boolean>(resolve=>{
            if(tt.getImRankList){
                tt.getImRankList({
                    relationType: "default", //只展示好友榜
                    dataType: 0, //只圈选type为数字类型的数据进行排序
                    rankType: "all", //每月1号更新，只对当月1号到现在写入的数据进行排序
                    suffix: "关", //数据后缀，成绩后续默认带上 “分”
                    rankTitle: "排行榜", //标题
                    success(res) {
                      console.log(`getImRankData success res: ${JSON.stringify(res)}`);
                      resolve(true);
                    },
                    fail(res) {
                      console.log(`getImRankData fail res: ${res.errMsg}`);
                      resolve(true);
                    },
                });
            }else{
                console.log("展示排行榜错误  头条基础版本库不支持API");
                resolve(false);
            }
        });
    }


    //选择登录失败
    private async goLoginSelect(title: string): Promise<boolean> {
        //
        console.debug('tt 授权弹提示框');
        return new Promise(resolve => {
            this.showModal({
                title: title,
                content: '此功能需要授权登录账号才可使用',
                confirmText: '登录',
                cancelText: '取消',
                showCancel: true,
                success: (result: { errMsg: string, confirm: boolean, cancel: boolean }) => {
                    console.debug('tt 授权弹提示框完毕');
                    //选择登录
                    if (result.confirm) {
                        console.debug('tt 拉起登录');
                        //
                        this.login({
                            force: true,
                            success: (res) => {
                                console.debug('tt 登录完成 1');
                                // this.m_currLoginCode = res.code;

                                //可先调用拉起设置
                                // tt.openSetting({
                                //     success:(res) => {
                                //         console.log(res);
                                //     },
                                //     fail:(res) => {
                                //         console.log(`openSetting 调用失败`);
                                //     },
                                // });
                                //授权
                                this.authorize({
                                    scope: "scope.userInfo",
                                    success: () => {
                                        console.debug('tt 授权成功');
                                        //信息获取
                                        this.getUserInfo({
                                            success: (res) => {
                                                console.debug('tt 获取用户信息成功');
                                                resolve(true);
                                            },
                                            fail: () => {
                                                resolve(false);
                                            }
                                        });
                                    },
                                    fail: () => {
                                        resolve(false);
                                    }
                                })
                                // //获取唯一ID
                                // if (this.m_UniqueId) {
                                //     return;
                                // }
                                // //
                                // gameHttp_module.getUserWxIdentifyByCode(this.m_currLoginCode, (res) => {
                                //     console.debug('我的唯一ID', res);
                                //     this.m_UniqueId = res;
                                //     gameHttp_module.getUserWebInfo(this.m_UniqueId, (res) => {
                                //         this.m_curWebUserInfo = JSON.parse(res);
                                //         console.debug('读取到的数据', res);
                                //         this.onWebInfoGetOnce();
                                //     }, res1 => {
                                //         this.m_curWebUserInfo = {
                                //             m_coins: this.m_normalCoins,
                                //             m_devilCurrLevel: 0,
                                //             m_synthesisEquipmentList: [],
                                //             m_unlockStamp: 0,
                                //         }
                                //     });
                                // })
                            },
                            fail: () => {
                                resolve(false);
                            }
                        });
                    } else {
                        resolve(false);
                    }
                }, fail() {
                    resolve(false);
                }
            })
        })
    }

    private async isAntherUserInfo(): Promise<boolean> {
        return new Promise(resolve => {
            tt.getSetting({
                //Function		否	接口调用成功的回调函数	1.3.0
                success: (res: { authSetting: { 'scope.userInfo': boolean } }) => {
                    console.debug('tt 设置结果', res);
                    resolve(res.authSetting["scope.userInfo"]);
                },
                //
                fail: () => {
                    resolve(false);
                },
            });
        })
    }

    navigateToMiniGame(appId: string, successCallback?: () => void, failCallback?: () => void): void {
        console.error('#1000102904 未实现跳转');
    }
}
/**
 //均衡器
 const equalizer = ctx.createEqualizer();
 // 或者ctx.createEqualizer(7.0, -8.0, 9.6, 9.6, 5.6, 1.6, -4.0, -8.0, -10.4, -11.2, -11.2)
 equalizer.setAMPs(
 7.0,
 -8.0,
 9.6,
 9.6,
 5.6,
 1.6,
 -4.0,
 -8.0,
 -10.4,
 -11.2,
 -11.2
 );
 source.connect(equalizer);
 equalizer.connect(ctx.destination);
 */
/**
 //start 混响
 const reverb = ctx.createReverb();
 //KTV 效果 一些常见参数可以参考ReverbNode节点内容
 reverb.roomSize = 1.17;
 reverb.damping = 0.89;
 reverb.stereoDepth = 0.86;
 reverb.dry = 1.6;
 reverb.wet = 0.41;
 source.connect(reverb);
 reverb.connect(ctx.destination);
 //end
 */


















